{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Linear Regression: The TensorFlow Way\n",
    "\n",
    "For this script, we introduce how to perform linear regression in the context of TensorFlow.\n",
    "\n",
    "We will solve the linear equation system:\n",
    "\n",
    "$$ y = Ax + b$$\n",
    "\n",
    "With the Sepal length (y) and Petal width (x) of the Iris data.\n",
    "\n",
    "Performing linear regression in TensorFlow is a lot easier than trying to understand Linear Algebra or Matrix decompositions for the prior two recipes.  We will do the following:\n",
    "\n",
    " 1. Create the linear regression computational graph output. This means we will accept an input, $x$, and generate the output, $Ax + b$.\n",
    " 2. We create a loss function, the L2 loss, and use that output with the learning rate to compute the gradients of the model variables, $A$ and $b$ to minimize the loss.\n",
    " \n",
    "The benefit of using TensorFlow in this way is that the model can be routinely updated and tweaked with new data incrementally with any reasonable batch size of data.  The more iterative we make our machine learning algorithms, the better.\n",
    "\n",
    "We start by loading the necessary libraries."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from sklearn import datasets\n",
    "from tensorflow.python.framework import ops\n",
    "ops.reset_default_graph()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We create a graph session."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "sess = tf.Session()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next we load the Iris data from the Scikit-Learn library."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Load the data\n",
    "# iris.data = [(Sepal Length, Sepal Width, Petal Length, Petal Width)]\n",
    "iris = datasets.load_iris()\n",
    "x_vals = np.array([x[3] for x in iris.data])\n",
    "y_vals = np.array([y[0] for y in iris.data])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "With most TensorFlow algorithms, we will need to declare a batch size for the placeholders and operations in the graph.  Here, we set it to 25.  We can set it to any integer between 1 and the size of the dataset.\n",
    "\n",
    "For the effect of batch size on the training, see [Chapter 2: Batch vs Stochastic Training](https://github.com/nfmcclure/tensorflow_cookbook/tree/master/02_TensorFlow_Way/06_Working_with_Batch_and_Stochastic_Training)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Declare batch size\n",
    "batch_size = 25"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We now initialize the placeholders and variables in the model."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Initialize placeholders\n",
    "x_data = tf.placeholder(shape=[None, 1], dtype=tf.float32)\n",
    "y_target = tf.placeholder(shape=[None, 1], dtype=tf.float32)\n",
    "\n",
    "# Create variables for linear regression\n",
    "A = tf.Variable(tf.random_normal(shape=[1,1]))\n",
    "b = tf.Variable(tf.random_normal(shape=[1,1]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We add the model operations (linear model output) and the L2 loss."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Declare model operations\n",
    "model_output = tf.add(tf.matmul(x_data, A), b)\n",
    "\n",
    "# Declare loss function (L2 loss)\n",
    "loss = tf.reduce_mean(tf.square(y_target - model_output))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We have to tell TensorFlow how to optimize and back propagate the gradients.  We do this with the standard Gradient Descent operator (`tf.train.GradientDescentOptimizer`), with the learning rate argument of $0.05$.\n",
    "\n",
    "Then we initialize all the model variables."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Declare optimizer\n",
    "my_opt = tf.train.GradientDescentOptimizer(0.05)\n",
    "train_step = my_opt.minimize(loss)\n",
    "\n",
    "# Initialize variables\n",
    "init = tf.initialize_all_variables()\n",
    "sess.run(init)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We start our training loop and run the optimizer for 100 iterations."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Step #25 A = [[ 1.7111783]] b = [[ 3.52971959]]\n",
      "Loss = 0.895595\n",
      "Step #50 A = [[ 1.36974895]] b = [[ 4.03345919]]\n",
      "Loss = 0.279897\n",
      "Step #75 A = [[ 1.17453122]] b = [[ 4.32749462]]\n",
      "Loss = 0.240451\n",
      "Step #100 A = [[ 1.09145582]] b = [[ 4.51084995]]\n",
      "Loss = 0.266713\n"
     ]
    }
   ],
   "source": [
    "# Training loop\n",
    "loss_vec = []\n",
    "for i in range(100):\n",
    "    rand_index = np.random.choice(len(x_vals), size=batch_size)\n",
    "    rand_x = np.transpose([x_vals[rand_index]])\n",
    "    rand_y = np.transpose([y_vals[rand_index]])\n",
    "    sess.run(train_step, feed_dict={x_data: rand_x, y_target: rand_y})\n",
    "    temp_loss = sess.run(loss, feed_dict={x_data: rand_x, y_target: rand_y})\n",
    "    loss_vec.append(temp_loss)\n",
    "    if (i+1)%25==0:\n",
    "        print('Step #' + str(i+1) + ' A = ' + str(sess.run(A)) + ' b = ' + str(sess.run(b)))\n",
    "        print('Loss = ' + str(temp_loss))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We pull out the optimal coefficients and get the best fit line."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Get the optimal coefficients\n",
    "[slope] = sess.run(A)\n",
    "[y_intercept] = sess.run(b)\n",
    "\n",
    "# Get best fit line\n",
    "best_fit = []\n",
    "for i in x_vals:\n",
    "  best_fit.append(slope*i+y_intercept)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Plot the results with Matplotlib.  Along with the linear fit, we will also plot the L2 loss over the model training iterations."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n17T7ePODc3NmzpzJli1bWL16Nddddx233norF1xwQUz5VTXuF6iI8OGHH7J161Zmz57NU089xSOP\nPOK7PMNIVxLxP5vMuubMmU+vXmfRocNwevU6izlz5idNvoSQ6kBSTQg4pV5EOr5ixSrt3fsqhe0K\nqrBde/e+SlesWOWZPtH5aygqKtLZs2fXO/bWW29pTk6OLl26VFVVZ86cqYcffrjm5+drz549tbS0\ntDZtz549NScnR9u2bavt2rXTBQsWaEVFhR533HHauXNn7dKliw4dOlS3bNkSUQYR0YqKitrf55xz\njo4dO1ZVVZctW6YlJSXaoUMHPfTQQ/XFF1+sTTdixAgdP368qqqWlZXpfvvtp3fccYfuu+++2r17\nd506daqqqj788MPasmVL3WuvvbRdu3Z62mmnqarqLbfcoj169NB27drpwQcfrK+//rqnfJHuoWE0\nhUT9zyarrvLyeZqbe169PLm552l5+byEyxeK+//l773rN2PQW1MVxNChpSE3QmtvyNChpZ7pE52/\nBi8Foeq8+B966CFVVS0vL9clS5aoqurixYu1W7du+sILL6iq6qpVqzQnJ0erq6tr83722Wf62muv\n6a5du/Srr77S4uJiveKKKyLKEKogli5dqt26ddOpU6fqrl279IADDtBbbrlFd+3apa+//rq2a9dO\nly9frqoNFURubq6Wlpbq7t279T//+Y+2adNGq6qqGqRVVf3kk0+0oKBAN2zYoKqqq1ev1hUrVnjK\nZwrCSASJ+p9NVl1FRWd65ikqOjPh8oUSj4LI2iGm+tPua4h92n28+Ruje/fubNrkLJo3cOBADjnk\nEAAOPfRQhgwZQnl5eb30zn126N27N8cffzy5ubl07tyZK664okH6cI444gg6d+7M6aefzkUXXcSI\nESNYsGABO3bs4NprryU3N5dBgwZxyimnMH36dM8yWrVqxfjx42nRogUnnXQSbdu25ZNPPvFM26JF\nC3bu3MmSJUvYvXs3PXv2pFevXjG3j2E0lWT/z8Zb1+bNeZ55qqrCj6UPGR9qIxLxTrtP9rT9devW\n0alTJwAWLlzI9ddfz5IlS9i5cyc7d+7knHPOiZh348aNXHbZZcydO5ft27ezZ8+e2rIi8d577zV4\nQVdWVlJQUFDvWGFhIevWrfMso3PnzvUM5W3atGH79u2eaXv37s3dd99NaWkpy5Yt4xe/+AV33HEH\n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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7fda2812a668>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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\nlfNWdiDdvXu3P/TQQ7558+Z90woLC/3MM8/03/3udxUus3jxYj/22GO9Y8eOPm7cOH/88cd9+fLl\nXlxcXOH8v//97/0Xv/jFvud//OMffcKECfue5+fne2Zmpp944ok+Z84cLy0t9e3bt/uQIUP8D3/4\nw775Xn31VU9PT/f09HRv2LChd+nSxUePHu3vvfdelb+7iCSOIw2Gevc5hor8+c9/ZvTo0fTt27dG\n2y0oKODkk0/m7LPP5re//S1du3YF4MUXX2TixIlMmTKFU089lblz5/Luu+/y0UcfsWnTJnr37k2f\nPn3IyMggPT2dpKQkbr31VhYvXky7du0A2Lp1Kz179uSDDz6gefPmjBo1ihEjRjB16tTQd1Dk5eUx\nbNgwLrzwQhYvXsySJUt4/PHHGTZsGEVFRaxbt4558+Zx5513kpGRwe23387QoUMxO7xLoHNzc5k9\nezbjxo2jYcOGFc7j7qxatYqFCxdSWlpKcnIyycnJDB06lNTU1NC8paWlzJ8/n0GDBh12TSL1jW6J\nUcutXbuWO+64g5kzZ9KtWzd69uzJRx99xKuvvsqAAQMOmH/btm37DuBr165l/fr1fP/990ycOJEx\nY8aE5r3nnnuYPXs2K1eu5JprruG6666r8OC5du1axowZw/nnn88tt9xCkyZNDpinqKiIp59+mrvu\nuovi4mJGjBjBGWecweDBg8nIyKBRo0ZV/p6FhYU8+OCD3HPPPXTu3Jn27dvz0ksv0apVKyASBq+9\n9hpPPfUUn376KU2aNGHAgAE0bNiQ4uJiduzYwdKlS7n33nu56KKLMDNycnK48sorWbBgAZdddhkP\nPvhgTL94qaSkhAYNGsRsfSI1RcGQIIqKisjOzuaTTz7ht7/9LW3btj3iNnfu3MnJJ5/MTTfdxLhx\n42qgysgBfPny5bz77ru88847fPnll6xfv54OHTpwzDHHMHDgQAYNGsSAAQPYtWsXK1asYOXKlUyf\nPp1evXoxdepUjjnmGK677jreeecd3nzzTXbt2sU111zDxo0b+eMf/8jQoUNJT08/YN0ff/wxV111\nFe3atWPAgAH87W9/4/bbb2fcuHGce+65HH300Tz11FOhnkhJSQn5+fnk5eWxdetWUlJSaN26Na1b\nt6Zp06ahoNy1axerV69m7dq1pKSk0L59e9q3b0/z5s1JTk4mKSmJjRs3MnPmTF555RWys7O59NJL\nuffee2nZsuUhbcfNmzfz9ttvs2rVKm688UZSUlJCr7/xxhv897//5corr9zXCxSpKQkbDGY2Crif\nyCWzT7r7nyqYp84EQyIrLi7mu+++4+uvv+bzzz9n/vz5LFiwgBYtWtC9e3d69OjBGWecwZlnnhla\n7uGHHyYrK4ukpCRuu+02rrzySpKTq/4KkOLiYh5++GGWLVvG5MmTOeqoo4DIQf3CCy8kOTmZcePG\n8cEHH/DBBx+wbNkyWrZsSdu2bUlNTWXnzp3k5+eTn59PcXExKSkpNGvWjNLSUgoKCujatStdunRh\n165dbNq0iU2bNrFz506Ki4txd1q0aMGYMWO48MILOeWUU8jKymLWrFk8+eSTjBgxYl+dBQUFLFy4\nkC+//JJFixaxe/dukpOTadCgAcuXL2fhwoWMGDGCpKQkVqxYweuvv05GRgbuzt13382jjz7KmWee\nycyZM5kwYQLXX399hWG5cOFC3n77bXJzc8nNzaWoqIg77riD4447LjTf1q1bWbp0Kf3796dp06b7\nprs7GzZsYPv27fuG7IqKisjNzWXDhg1s3ryZpk2b0qpVK1JTU+nfv3+FIfjVV1+RmppKhw4dKh3S\nW716Nc888wytW7fed4eB5s2bs2HDBr777jv27NnD4MGDQ/VVV1FREdOnT2fbtm1MnDixxm9nU1JS\nwvz583F3mjVrRrNmzejatesB++v69evJysoiIyODU089lSFDhlTYA6/M9u3bycrK4tVXX+W8887j\n0ksvpX///jX6u0CCBoOZJQFfAWcA3wGfARe5+7L95lMwBLKzs8nMzIx3GYds8eLFdOrUqUbeFRcW\nFnLNNdewaNEiLrjgAoYNG0b//v0rPZdRVFTEzp07933O5KijjqpyKKq0tBTggHnmzJnD5ZdfTsOG\nDdmxYwfbtm0jKSmJvn370r9/f/r160dKSgolJSWUlpaSnp7O8OHDadKkCe7Offfdx5QpU3j66aeZ\nNm0ay5cv5/XXXyctLY3169czdepUnnrqKU4//XQuv/xyRo4cyZIlS7j99tv597//zbhx40hPT6dj\nx45s3LiRu+++mzvvvJMrrriCuXPnsnLlSm677TY6duzIihUr6NOnD/369eObb77hv//9L6WlpbRp\n04bi4mKKi4tJTk6mU6dOdOrUibZt27Jnzx62bt3Kli1bWLZsGePHj2fSpElkZGTw2muvMXXqVNas\n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\nYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7fda2806d9e8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Plot the result\n",
    "plt.plot(x_vals, y_vals, 'o', label='Data Points')\n",
    "plt.plot(x_vals, best_fit, 'r-', label='Best fit line', linewidth=3)\n",
    "plt.legend(loc='upper left')\n",
    "plt.title('Sepal Length vs Pedal Width')\n",
    "plt.xlabel('Pedal Width')\n",
    "plt.ylabel('Sepal Length')\n",
    "plt.show()\n",
    "\n",
    "# Plot loss over time\n",
    "plt.plot(loss_vec, 'k-')\n",
    "plt.title('L2 Loss per Generation')\n",
    "plt.xlabel('Generation')\n",
    "plt.ylabel('L2 Loss')\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
